/*****************************************************************************
 * set.h: h264 encoder
 *****************************************************************************
 * Copyright (C) 2003 Laurent Aimar
 * $Id: set.h,v 1.1 2004/06/03 19:27:07 fenrir Exp $
 *
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
 *****************************************************************************/

#ifndef _SET_H
#define _SET_H 1

enum profile_e
{
    PROFILE_BASELINE = 66,
    PROFILE_MAIN     = 77,
    PROFILE_EXTENTED = 88,
    PROFILE_HIGH    = 100,
    PROFILE_HIGH10  = 110,
    PROFILE_HIGH422 = 122,
    PROFILE_HIGH444 = 144
};

enum cqm4_e
{
    CQM_4IY = 0,
    CQM_4PY = 1,
    CQM_4IC = 2,
    CQM_4PC = 3
};
enum cqm8_e
{
    CQM_8IY = 0,
    CQM_8PY = 1
};

typedef struct
{
    int i_id;  //a unique identifier sps的id号

    int i_profile_idc;//指明所用的profile
    int i_level_idc;//指明所用的level

    int b_constraint_set0;
    int b_constraint_set1;
    int b_constraint_set2;

    int i_log2_max_frame_num;//表示图像解码顺序的最大取值

    int i_poc_type;
    /* poc 0 */
    int i_log2_max_poc_lsb;  //LSB：最低有效位
    /* poc 1 */
    int b_delta_pic_order_always_zero;
    int i_offset_for_non_ref_pic;
    int i_offset_for_top_to_bottom_field;
    int i_num_ref_frames_in_poc_cycle;
    int i_offset_for_ref_frame[256];

    int i_num_ref_frames;//参考帧的最大序列长度
    int b_gaps_in_frame_num_value_allowed;
    int i_mb_width;//宽度上有多少宏块
    int i_mb_height;//高度上有多少宏块
    int b_frame_mbs_only;
    int b_mb_adaptive_frame_field; //Macroblock Adaptive Frame Field Coding (MBAFF)
    int b_direct8x8_inference;  //Specifies how certain B macroblock motion vectors are derived //指明b片的直接和skip模式下运动矢量的预测方法

    int b_crop;
    struct
    {
        int i_left;
        int i_right;
        int i_top;
        int i_bottom;
    } crop;

    int b_vui;
    struct
    {
        int b_aspect_ratio_info_present;
        int i_sar_width;
        int i_sar_height;

        int b_timing_info_present;
        int i_num_units_in_tick;
        int i_time_scale;
        int b_fixed_frame_rate;

        int b_bitstream_restriction;
        int b_motion_vectors_over_pic_boundaries;
        int i_max_bytes_per_pic_denom;
        int i_max_bits_per_mb_denom;
        int i_log2_max_mv_length_horizontal;
        int i_log2_max_mv_length_vertical;
        int i_num_reorder_frames;
        int i_max_dec_frame_buffering;

        /* FIXME to complete */
    } vui;

    int b_qpprime_y_zero_transform_bypass;

} x264_sps_t; //视频序列共有的参数。

typedef struct
{
    int i_id;//pps的的序号，在片头被引用
    int i_sps_id;  //a unique identifier  本图像参数集所引用的序列参数集的序号

    int b_cabac;//是否采用cabac编码，为1就是用cabac，为0则使用calvc

    int b_pic_order;//poc的三种计算方法在片层还各需要用一些句法元素作为参数；
    int i_num_slice_groups;//加1表示图像中片组的个数

#if 0
    /* FIXME: if this stuff is ever needed, move SPS/PPS from x264_t
     * to the heap, to avoid excessive memcpy'ing with threads. */
    int i_slice_group_map_type;
    /* i_slice_group_map_type == 0 */
    int i_run_length[256];      /* FIXME */
    /* i_slice_group_map_type == 2 */
    int i_top_left[256];        /* FIXME */
    int i_bottom_right[256];    /* FIXME */
    /* i_slice_group_map_type == 3, 4, 5 */
    int b_slice_group_change_direction;
    int i_slice_group_change_rate;
    /* i_slice_group_map_type == 6 */
    int i_pic_size_in_map_units;
    int i_slice_group_id[256];  /* FIXME */
#endif

    int i_num_ref_idx_l0_active;// 指明目前参考帧队列的长度，即有多少个参考帧（短期和长期），用于list0
    int i_num_ref_idx_l1_active;// 指明目前参考帧队列的长度，即有多少个参考帧（短期和长期），用于list1

    int b_weighted_pred;//是否开启P帧和SP帧的加权预测
    int b_weighted_bipred;//开启B帧的加权预测

    int i_pic_init_qp;// 加26后用以指明亮度分量的量化参数的初始值
    int i_pic_init_qs;// 同上，只是用于SP和SI

    int i_chroma_qp_index_offset;// 色度分量的量化参数是根据亮度分量的量化参数计算出来的，本句法元素用以// 指明计算时用到的参数表示为在 QPC 值的表格中寻找 Cb色度分量而应加到// 参数 QPY 和 QSY 上的偏移。该值应在-12 到 +12范围内（包括边界值）

    int b_deblocking_filter_control;// 编码器可以通过句法元素显式地控制去块滤波的强度
    int b_constrained_intra_pred;// 控制PB帧的帧内编码，在P和B帧中，帧内编码的宏块的邻近宏块可能采用帧间编码
    int b_redundant_pic_cnt;// 对于那些属于基本编码图像的条带和条带数据分割块，redundant_pic_cnt等于0；

    int b_transform_8x8_mode;

    int i_cqm_preset;// 外部量化矩阵的设置
    const uint8_t *scaling_list[6]; /* could be 8, but we don't allow separate Cb/Cr lists */// 缩放比例列表，could be 12, but we don't allow separate Cb/Cr lists

} x264_pps_t;

/* default quant matrices */
static const uint8_t x264_cqm_jvt4i[16] =
{
      6,13,20,28,
     13,20,28,32,
     20,28,32,37,
     28,32,37,42
};
static const uint8_t x264_cqm_jvt4p[16] =
{
    10,14,20,24,
    14,20,24,27,
    20,24,27,30,
    24,27,30,34
};
static const uint8_t x264_cqm_jvt8i[64] =
{
     6,10,13,16,18,23,25,27,
    10,11,16,18,23,25,27,29,
    13,16,18,23,25,27,29,31,
    16,18,23,25,27,29,31,33,
    18,23,25,27,29,31,33,36,
    23,25,27,29,31,33,36,38,
    25,27,29,31,33,36,38,40,
    27,29,31,33,36,38,40,42
};
static const uint8_t x264_cqm_jvt8p[64] =
{
     9,13,15,17,19,21,22,24,
    13,13,17,19,21,22,24,25,
    15,17,19,21,22,24,25,27,
    17,19,21,22,24,25,27,28,
    19,21,22,24,25,27,28,30,
    21,22,24,25,27,28,30,32,
    22,24,25,27,28,30,32,33,
    24,25,27,28,30,32,33,35
};
static const uint8_t x264_cqm_flat16[64] =
{
    16,16,16,16,16,16,16,16,
    16,16,16,16,16,16,16,16,
    16,16,16,16,16,16,16,16,
    16,16,16,16,16,16,16,16,
    16,16,16,16,16,16,16,16,
    16,16,16,16,16,16,16,16,
    16,16,16,16,16,16,16,16,
    16,16,16,16,16,16,16,16
};

void x264_cqm_init( x264_t *h );
int  x264_cqm_parse_file( x264_t *h, const char *filename );

#endif
